﻿using System;
using System.Drawing;
using RoboRallyAPI;

namespace RoboRally
{
	/// <summary>
	/// Adds engine items to the player object.
	/// </summary>
	public class PlayerInternal : Player
	{
		public PlayerInternal(string guid, Point archive, Robot robot, Point[] flags, IPlayer playerEngine, Color spriteColor)
			: base(guid, archive, robot, flags)
		{
			PlayerEngine = playerEngine;
			SpriteColor = spriteColor;
		}

		/// <summary>
		/// The player's AI engine.
		/// </summary>
		public IPlayer PlayerEngine { get; private set; }

		/// <summary>
		/// The color for this player on the status window.
		/// </summary>
		public Color SpriteColor { get; private set; }

		/// <summary>
		/// Decrease lives by 1. If decreased to 0, mark player destroyed.
		/// </summary>
		public void DecreaseLives()
		{
			Lives--;
			Damage = 10; // mark as destroyed till next turn
			Robot.Location = new BoardLocation(new Point(-1, -1), Robot.Location.Direction);

			if (Mode == MODE.DEAD)
				Cards = new Card[0];
		}

		/// <summary>
		/// Player touched the flag at this location.
		/// </summary>
		/// <param name="position">The map square touched.</param>
		public void TouchedFlag(Point position)
		{
			Archive = position;
			// has to be the next one
			foreach (FlagState flagOn in FlagStates)
			{
				if (flagOn.Position == position)
				{
					flagOn.Touched = true;
					break;
				}
				if (!flagOn.Touched)
					break;
			}
		}

		/// <summary>
		/// Repair (decrease Damage by 1) for this player. Set as new Archive position for player.
		/// </summary>
		/// <param name="position">The map location repaired at.</param>
		public void Repair(Point position)
		{
			Archive = position;
			Damage = Math.Max(0, Damage - 1);
		}

		/// <summary>
		/// Set the new Archive position for the player.
		/// </summary>
		/// <param name="position">The map location for the new archive position.</param>
		public void SetArchive(Point position)
		{
			Archive = position;
		}

		/// <summary>
		/// Increase damage by 1. If increased to 10, mark dead.
		/// </summary>
		public void IncreaseDamage()
		{
			Damage++;
			if (Damage < 10) 
				return;

			Robot.Location = new BoardLocation(new Point(-1, -1), MapSquare.DIRECTION.NORTH);
			DecreaseLives();
		}

		/// <summary>
		/// Reset damage back to 0.
		/// </summary>
		public void UnDestroy()
		{
			Damage = 2;
			PowerMode = POWER_MODE.UP;
		}

		/// <summary>
		/// Power down this player.
		/// </summary>
		public void PowerDown()
		{
			PowerMode = POWER_MODE.DOWN;
			Damage = 0;
		}

		/// <summary>
		/// Power up this player.
		/// </summary>
		public void PowerUp()
		{
			PowerMode = POWER_MODE.UP;
		}

		/// <summary>
		/// Announce power down for this player. Will power down at the end of the turn on.
		/// </summary>
		public void AnnouncePowerMode()
		{
			PowerMode = POWER_MODE.ANNOUNCED;
		}
	}
}
